#include <iostream>
#include <string>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

// 示例类：玩家信息
class Player {
public:
    std::string name;
    int level;
    double health;
    std::vector<std::string> inventory;

    // 默认构造函数
    Player() = default;

    // 构造函数
    Player(const std::string& name, int level, double health)
        : name(name), level(level), health(health) {}

    // 转换为JSON
    json to_json() const {
        return json{
            {"name", name},
            {"level", level},
            {"health", health},
            {"inventory", inventory}
        };
    }

    // 从JSON创建对象
    static Player from_json(const json& j) {
        Player player;
        player.name = j["name"].get<std::string>();
        player.level = j["level"].get<int>();
        player.health = j["health"].get<double>();
        player.inventory = j["inventory"].get<std::vector<std::string>>();
        return player;
    }
};

// 为Player类添加NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE宏
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Player, name, level, health, inventory)

int main() {
    // 1. 基本JSON操作
    json j;
    j["name"] = "John";
    j["age"] = 30;
    j["is_active"] = true;
    j["skills"] = {"C++", "Python", "JavaScript"};

    // 序列化到字符串
    std::string serialized = j.dump(4); // 4是缩进空格数
    std::cout << "Serialized JSON:\n" << serialized << "\n\n";

    // 反序列化
    json parsed = json::parse(serialized);
    std::cout << "Parsed name: " << parsed["name"] << "\n\n";

    // 2. JSON与类的相互转换
    Player player("Hero", 10, 100.0);
    player.inventory = {"Sword", "Shield", "Potion"};

    // 类转JSON
    json playerJson = player.to_json();
    std::cout << "Player JSON:\n" << playerJson.dump(4) << "\n\n";

    // JSON转类
    Player newPlayer = Player::from_json(playerJson);
    std::cout << "New player name: " << newPlayer.name << "\n";
    std::cout << "New player level: " << newPlayer.level << "\n";
    std::cout << "New player health: " << newPlayer.health << "\n";
    std::cout << "New player inventory: ";
    for (const auto& item : newPlayer.inventory) {
        std::cout << item << " ";
    }
    std::cout << "\n\n";

    // 示例1：解析无效的JSON
    try {
        json invalidJson = json::parse("{invalid json}");
    } catch (const json::parse_error& e) {
        std::cout << "JSON解析错误: " << e.what() << "\n";
    }

    // 示例2：访问不存在的字段
    try {
        std::string nonExistent = playerJson["non_existent_field"].get<std::string>();
    } catch (const json::type_error& e) {  // 修改为正确的异常类型
        std::cout << "JSON类型错误: " << e.what() << "\n";
    } catch (const json::exception& e) {    // 可以添加一个通用的捕获
        std::cout << "其他JSON错误: " << e.what() << "\n";
    }

    return 0;
}